package com.liuqing.www.phone.server.底层消息;

import com.gwsoft.common.ConvertUtil;
import com.gwsoft.logic.NetCommand;
import com.gwsoft.logic.common.CommandModel;

/**
 * @author kevinbian E-mail: langzibian@yahoo.com.cn
 * @version 创建时间：2011-4-29 下午02:14:37
 * 
 * 
 * 	消息序列号	4字节
	消息指令号	4字节 消息指令号为4字节的整数，
					 高8位（第一个字节）为服务器标志，
					 第二个字节为消息分类信息，
					 低16位为消息指令的编号。
	消息版本	2字节
	消息信息 加密，压缩	1字节
	消息长度	4字节
	消息内容	消息长度
 */
public class DataPackHeader {
	
	private int cmdid ;
	
	private int res_cmdid ;
	
	
	public static final int headerLength = 15 ;
	public static final int contentPackLength = 4 ;
	
	byte[] header = new byte[headerLength];
	
	byte[] reheader = new byte[headerLength];
	
	private CommandModel cmdModel = null ;							//命令对象
	
	private byte[] contentLengthByte = new byte[contentPackLength] ;		//消息体长度字节数组
	private int contentLength = 0 ;								//消息体长度
	
	public static int messageSq = 0; 								//消息序列号
    private static final byte serverFlag = 0;						//服务器标志
    public static short messageCmdNum = 0;							//消息指令号
    public static short messageVersion =0;							//消息版本信息
    
    public DataPackHeader(byte[] headerpack) {
		try {
			header(headerpack) ;
			cmd() ;
		} catch (Exception e) {
			e.printStackTrace();
		}
		cmdModel = NetCommand.getCommand(cmdid) ;
		try {
			if(cmdModel == null){
				throw new Exception("未找到命令"+Integer.toHexString(cmdid)) ;
			}
		} catch (Exception e) {
			e.printStackTrace() ;
		}
		res_cmdid = cmdModel.getRes_cmd() ;
		System.out.println("client cmdid " + Integer.toHexString(cmdid));
	}
	
	private void header(byte[] headerpack) throws Exception{
		if(headerpack.length < headerLength){
			throw new Exception("消息长度 小于 消息头长度") ;
		}
		header = headerpack ;
		System.arraycopy(header, headerLength - contentPackLength , contentLengthByte, 0, contentPackLength);
		contentLength = ConvertUtil.byteToInt(contentLengthByte) ;
		System.out.println("消息长度为："+contentLength);
		
	}
	
	/**
	 * 命令(分类信息)
	 */
	private void cmd(){
		byte[] cmd = new byte[4] ;
		for(int i=0 ;i<cmd.length ; i++){
			cmd[i] = header[i + 4] ;
		}
		cmdid = byteArray4ToInt(cmd) ;
	}
	
	public int toInt(byte b) {
		if (b >= 0)
			return (int) b;
		else
			return (int) (b + 256);
	} 
	
	public int byteArray4ToInt(byte[] byteValue) {
		if (byteValue.length != 4)
			return 0;

		int intValue = 0;
		try {
			intValue = toInt(byteValue[0]);
			intValue = (intValue << 8) + toInt(byteValue[1]);
			intValue = (intValue << 8) + toInt(byteValue[2]);
			intValue = (intValue << 8) + toInt(byteValue[3]);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return intValue;
	}
	
	public byte[] fullHeader(int contentLength){
//		序号4字节
		byte[] suq = ConvertUtil.int4bytes(++ messageSq) ;
		for(int i=0 ;i<suq.length ; i++){
			reheader[i] = suq[i] ;
		}
//		指令号4字节(第一字节server flag,二字节为命令号cmdid ,3,4字节指令编号)
		byte[] cmds = ConvertUtil.int4bytes(res_cmdid) ;
		for(int i=0 ;i<cmds.length ; i++){
			reheader[i + 4] = cmds[i] ;
		}
		
//		消息版本
		reheader[8] = 0 ;
		reheader[9] = 1 ;
//		压缩加密属性
		reheader[10] = 0 ;
//		内容长度
		byte[] length = ConvertUtil.int4bytes(contentLength) ;
		reheader[11] = length[0] ;
		reheader[12] = length[1] ;
		reheader[13] = length[2] ;
		reheader[14] = length[3] ;
		
		return reheader ;
	}
	
	public static byte[] fullHeader(int res_cmdid ,int contentLength){
//		序号4字节
		byte[] suq = ConvertUtil.int4bytes(++ messageSq) ;
		byte[] reheader = new byte[headerLength];
		for(int i=0 ;i<suq.length ; i++){
			reheader[i] = suq[i] ;
		}
//		指令号4字节(第一字节server flag,二字节为命令号cmdid ,3,4字节指令编号)
		byte[] cmds = ConvertUtil.int4bytes(res_cmdid) ;
		for(int i=0 ;i<cmds.length ; i++){
			reheader[i + 4] = cmds[i] ;
		}
		
//		消息版本
		reheader[8] = 0 ;
		reheader[9] = 1 ;
//		压缩加密属性
		reheader[10] = 0 ;
//		内容长度
		byte[] length = ConvertUtil.int4bytes(contentLength) ;
		reheader[11] = length[0] ;
		reheader[12] = length[1] ;
		reheader[13] = length[2] ;
		reheader[14] = length[3] ;
		return reheader ;
	}
	
	public Integer getCmdid() {
		return cmdid;
	}

	public void setCmdid(Integer cmdid) {
		this.cmdid = cmdid;
	}

	public CommandModel getCmdModel() {
		return cmdModel;
	}

	public void setCmdModel(CommandModel cmdModel) {
		this.cmdModel = cmdModel;
	}

	public byte[] getContentLengthByte() {
		return contentLengthByte;
	}

	public void setContentLengthByte(byte[] contentLengthByte) {
		this.contentLengthByte = contentLengthByte;
	}

	public int getContentLength() {
		return contentLength;
	}

	public void setContentLength(int contentLength) {
		this.contentLength = contentLength;
	}

	public int getRes_cmdid() {
		return res_cmdid;
	}

	public void setRes_cmdid(int res_cmdid) {
		this.res_cmdid = res_cmdid;
	}

	public byte[] getHeader() {
		return header;
	}

	public void setHeader(byte[] header) {
		this.header = header;
	}
}
